package com.yonyou.pmclouds.basecom.log;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 远程调用日志，暂未使用，跟dubbo注解模式好像不兼容
 * @author xiejianyu
 * 2019-09-02
@Aspect
@Component
@Data
 */
@Slf4j
public class RmiLogAspect {

    private long counter;

    private Map<String, Boolean> filterName;

    private int maxLength =2000;

    @Around("execution(* com.yonyou.pmclouds..rmiitf.*.*(..))")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        long seq;
        synchronized (log) {
            seq= counter++;
        }
        String methodName = joinPoint.getSignature().getName();

        StringBuffer sb=new StringBuffer();
        sb.append("requestSeq: "+seq);
        sb.append(",target: "+joinPoint.getTarget());
        sb.append(",methodName: "+methodName);

        boolean isLog=isLog(methodName);
        if(isLog){
            Object[] args = joinPoint.getArgs();
            sb.append(",args: ");
            for (Object object : args) {
                sb.append(object).append(",");
            }
        }
        if(log.isInfoEnabled()){
            String reqStr = sb.toString();
            if(reqStr.length()>maxLength){
                reqStr = reqStr.substring(0, maxLength);
            }
            log.info(reqStr);
        }
        Object ret;
        try {
            ret = joinPoint.proceed();
        } catch (Throwable e) {
            throw e;
        }
        String resStr="responseSeq: "+seq;
        if(isLog){
            resStr+=",return: "+ret;
        }
        if(log.isInfoEnabled()){
            if(resStr.length()>maxLength){
                resStr = resStr.substring(0,maxLength);
            }
            log.info(resStr);
        }
        return ret;
    }

    private boolean isLog(String methodName){
        if(filterName==null){
            return true;
        }

        Boolean r=filterName.get(methodName);
        if(r==null){
            return true;
        }
        return r;
    }
}